home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #3 / Amiga Plus CD - 1999 - No. 3.iso / System / delitracker_ii / developer / developer.deu next >
Text File  |  1995-07-19  |  36KB  |  844 lines

  1.  
  2.  
  3.                  $VER: Developer.deu V2.17 (18.07.1995)
  4.                    Copyright 1995 by Delirium Softdesign
  5.                       (Peter Kunath and Frank Riffel)
  6.  
  7.                   DeliTracker Development Documentation
  8.  
  9.  
  10.   1.ÜBERBLICK
  11.  
  12.   2.PLAYER
  13.    2.1 Normale Player
  14.    2.2 Custom Module
  15.    2.3 Interrupts
  16.  
  17.   3.GENIES
  18.    3.1 Generic Kind
  19.    3.2 Converter
  20.    3.3 Decruncher
  21.    3.4 NotePlayer
  22.  
  23.   4.TAGS
  24.  
  25.   5.DELITRACKER SUPPORT FUNKTIONEN
  26.  
  27.  
  28.   1.ÜBERBLICK
  29.  
  30.   DeliTracker kann mit externen Programmodulen erweitert werden. Diese
  31.   sehen vom DOS aus betrachtet genauso aus wie normale Objectfiles, mit
  32.   dem Unterschied allerdings, daß sie am Anfang des ersten Hunks eine
  33.   spezielle Struktur besitzen. Wenn DeliTracker ein solches Programmodul
  34.   nachlädt, wertet er diese Struktur aus. Sie besteht aus drei Teilen:
  35.   Einem Longword mit Code, zwei Longwords als Identifier und als letztes
  36.   einem Pointer auf ein Tagarray. Das erste Longword enthält normalerweise
  37.   moveq #-1,d0 gefolgt von einem rts Befehl. Dies soll einen Absturz
  38.   verhindern, wenn ein Player oder Genie irrtümlich vom Benutzer gestartet
  39.   wird. Um ein Programm zu erzeugen, das auch ohne DeliTracker lauffähig
  40.   ist, muß in das erste Longword in einen bra.w geändert werden, der dann
  41.   den eigentlichen Startupcode anspringt. Um die charakteristische Struktur
  42.   zu erzeugen sollte das PLAYERHEADER Macro aus 'deliplayer.i' verwendet
  43.   werden. Es hat zwei Parameter: einen Pointer auf ein Tagarray und
  44.   optional einen Pointer auf den Startupcode.
  45.  
  46.     PLAYERHEADER <tagarray>,[startup]
  47.  
  48.         tagarray        Pointer auf ein Tag Array, das mit TAG_DONE
  49.                         abgeschlossen sein muß.
  50.         startup         Pointer auf einen optionalen Startupcode. Nur
  51.                         notwendig, wenn das Programmodul auch ohne
  52.                         DeliTracker lauffähig sein soll. Diese Option
  53.                         kann z.B. für Debug-Zwecke verwendet werden.
  54.                         Bemerkung: Wenn der Startupcode angesprungen
  55.                         wird, muß die gesamte Initialisierung etc. ohne
  56.                         DeliTracker durchgeführt werden. In den meisten
  57.                         Fällen macht die Startup Option wenig Sinn und
  58.                         wird deshalb auch kaum benutzt.
  59.  
  60.   Die Tagliste enthält dabei alle Informationen, die DeliTracker wissen
  61.   muß. Wir verwenden ein Tagarray deshalb, weil es sehr flexibel und leicht
  62.   erweiterbar ist. Zusätzlich können die externen Programmodule noch die
  63.   GlobalStructure sowie die eingebauten Supportfunktionen benutzen. Im
  64.   Moment unterscheidet DeliTracker zwei verschiedene Typen von externen
  65.   Programmodulen:
  66.  
  67.         1) Player, um Module zu identifizieren und zu spielen
  68.  
  69.         2) Genies können viele andere Dinge machen. Unter anderem Module
  70.            konvertieren, Dateien entpacken oder Informationen anzeigen.
  71.  
  72.   Beide Arten können synchron oder asynchron laufen. Unter synchron
  73.   versteht man, daß der Player oder das Genie nicht als eigener Prozess
  74.   läuft. DeliTracker benutzt in diesem Fall echte Funktionsaufrufe (jsr)
  75.   zur Kommunikation. Im asynchronen Modus startet DeliTracker den Player
  76.   oder das Genie als eigenen Prozess und verwendet dann Messages um
  77.   Funktionen der externen Programmodule aufzurufen. Im allgemeinen laufen
  78.   Genies asynchron und Player synchron. Wenn ein Player oder ein Genie
  79.   asynchron läuft, dann muss man es durch Senden eines CTRL-C Signals an
  80.   den Prozeß beenden können. Offensichtlich sind DeliPlayer und DeliGenies
  81.   also sehr ähnlich. Sie werden von DeliTracker auch ziemlich gleich
  82.   verwaltet, wenn auch in zwei verschiedenen Listen. Jedes externe
  83.   Programmodul bei dem ein DTP_CustomPlayer, DTP_Check1 oder DTP_Check2
  84.   Tag benutzt wird, ist ein Player. Der Rest sind Genies.
  85.  
  86.   Wenn eine GUI vorhanden ist, sollten normalerweise folgende Menüpunkte
  87.   zur Verfügung stehen:
  88.  
  89.         Project
  90.                 About      A ?  Kurzinformation über das Programmodul
  91.                 ==============
  92.                 Save Prefs A S  Speichern der aktuellen Einstellungen
  93.                 ==============
  94.                 Hide       A H  GUI verbergen
  95.                 ==============
  96.                 Quit       A Q  Genie beenden (ebenso wie CTRL-C)
  97.  
  98.         Settings
  99.                 Activate   A A  Aktiviert das Fenster beim Öffnen des GUI
  100.                 Popup      A P  Öffnet das GUI nach dem Laden
  101.                 ==============
  102.                 Other settings  Hier können je nach Bedarf weitere
  103.                 ··············  Einstellungen folgen.
  104.  
  105.   Ein paar Anmerkungen:
  106.  
  107.   Bevor man einen DeliPlayer schreibt, sollte man sich die mitgelieferten
  108.   Beispielsourcen genau durchlesen. Um einen besseren Überblick davon zu
  109.   bekommen, wann und in welcher Reihenfolge DeliTracker die Funktionen des
  110.   Players aufruft, kann man den 'Testplayer.s' Source benutzen. Wenn eine
  111.   Konfigurationsdatei abgespeichert werden kann, sollte sie nicht nach
  112.   ENV:, sondern in das DeliTracker Konfiguartionsverzeichnis abgespeichert
  113.   werden. Der Pfad des Konfiguartionsverzeichnisses kann steht in der ENV-
  114.   Vaiable 'DeliConfig'. Falls diese nicht vorhanden ist, sollte stattdessen
  115.   'PROGDIR:DeliConfig' zum Abspeichern benutzt werden. Ein Player sollte
  116.   außerdem den Zustand der LED (Lowpass-Filter) unbeeinflußt lassen, da im
  117.   Optionfenster eine entsprechende Funktion existiert. Wenn von DeliTracker
  118.   eine Funktion des Players aufgerufen wird (außer bei den Interrupt-
  119.   Funktionen DTP_Interrupt und DTP_NoteSignal), enthält das Register a5
  120.   einen Pointer auf die Globale Struktur (Base). Da DeliTracker vor Aufruf
  121.   einer Routine (außer bei DTP_Interrupt und DTP_NoteSignal) alle Register
  122.   sichert, dürfen diese verändert werden.
  123.  
  124.  
  125.   2.PLAYERS
  126.  
  127.   Es ist relativ einfach, eine Replayroutine an DeliTracker anzupassen.
  128.   Alles was Sie tun müssen ist ein wenig Interfacecode zu schreiben. Dies
  129.   ist im allgemeinen recht einfach, denn DeliTracker stellt ihnen viele
  130.   hilfreiche Routinen zur Verfügung. Um ein neues Soundsystem anzupassen,
  131.   benötigen Sie zum einen den Quellcode oder ein linkbares Objektfile der
  132.   Replayroutine, zum anderen sollten mindestens ca. 5 Module zum Testen der
  133.   Funktionstüchtigkeit des Players vorhanden sein. Ganz am Anfang eines
  134.   Players muß die charakteristische Struktur stehen. DeliTracker unter-
  135.   scheidet dann zwei Arten von Playern: normale Player und Custom Module.
  136.  
  137.     2.1 Normale Player
  138.  
  139.     Normale Player identifizieren und spielen Module. Sie müssen immer eine
  140.     Check Routine besitzen. Der schematische Aufbau eines normalen Players
  141.     ist folgendermassen:
  142.  
  143.         { Playerheader  }       Kennzeichnet das Object als Player.
  144.         { TagArray      }       Beschreibung, was der Player kann.
  145.         { Interfacecode }       Playername/Registerumsetzung/Checkcode u.ä.
  146.         { Replaycode    }       Eigentlicher Musikabspielcode.
  147.         { evtl. Daten   }       und Daten
  148.  
  149.     Damit der Player die einzelnen Module unterscheiden kann, befindet sich
  150.     in jedem Player eine Erkennungsroutine, die auf ein zugehöriges Modul
  151.     testet und DeliTracker mitteilt, ob der Player dieses Modul spielen
  152.     kann oder nicht. Diese Routine prüft auf Stellen im Modul, die bei allen
  153.     Modulen eines Formats gleich sind. So z.B. auf 'M.K.' bei Offset $438
  154.     in ProTracker-Modulen. Nur auf einige wenige Sprungbefehle zu Prüfen
  155.     reicht im allgemeinen nicht aus, da viele Modulformate mit eingebauter
  156.     Abspielroutine Sprungbefehle am Anfang haben und der Player möglicher-
  157.     weise das falsche Modul erkennen könnte, was in den meisten Fällen zum
  158.     Absturz führt! Deshalb sollte die Check Routine auch eingehend getestet
  159.     werden. Es gibt zwei Typen von Check Funktionen, genau eine davon muß
  160.     der Player verwenden.
  161.  
  162.     a) DTP_Check1: Diese Check Funktion wird aufgerufen, wenn DeliTracker
  163.     1K des Files geladen hat. Der Vorteil ist, daß sich auch Player
  164.     realisieren lassen, die das Modul selbst nachladen. Der Nachteil ist,
  165.     daß der Player dann nicht von den Entpackroutinen in DeliTracker
  166.     profitiert. Meistens ist es deshalb schwerer, einen solchen Player zu
  167.     schreiben. Man sollte diesen Typ nur für Härtefälle verwenden, z.B.
  168.     wenn das Modul vom Player selbst geladen werden muß.
  169.  
  170.     b) DTP_Check2: Diese Check Routine wird aufgerufen, wenn das Modul
  171.     geladen und ggf. entpackt ist. Da ein Player mit dieser Check Funktion
  172.     im allgemeinen leichter zu schreiben ist, sollte im Normalfall diese
  173.     Check Routine verwendet werden.
  174.  
  175.     Egal welche Checkfunktion verwendet wird, wenn der Player das Modul
  176.     erkannt hat, muß er in d0.l=0 zurückliefern, wenn nicht d0.l<>0.
  177.  
  178.  
  179.     2.2 Custom Module
  180.  
  181.     Custom Module sind keine Module im herkömmlichen Sinn, sondern
  182.     besondere Player, die ein Modul beinhalten. Sie haben auch keine
  183.     Check Funktion, stattdessen muß der DTP_CustomPlayer Tag bzw. das
  184.     CUSTOM Flag (in DTP_Flags) verwendet werden. Mit diesem Interface
  185.     kann man auch die ausgefallensten Moduleformate an DeliTracker
  186.     anpassen. Sollten jedoch mehrere Module dieses Typs existieren, ist
  187.     es in jedem Fall ratsam, einen richtigen Player zu schreiben.
  188.  
  189.         { Playerheader  }       Kennzeichnet das Object als Player.
  190.         { TagArray      }       Beschreibung, was der Player kann.
  191.         { Interfacecode }       Routinen zur Registerumsetzung u.ä.
  192.         { Replaycode    }       Eigentlicher Musikabspielcode.
  193.         { evtl. Daten   }       und Daten
  194.         { SOUND DATEN   }       Das eigentliche Modul
  195.  
  196.  
  197.     2.3 Interrupts
  198.  
  199.     Hier gibt es eine Einteilung in zwei verschiedene Typen.
  200.  
  201.     a) Player die den DeliTracker Interrupt verwenden
  202.  
  203.      Vorteil:  Der Player ist vom Videomodus unabhängig.
  204.                Besitzt automatisch die Faster/Slower Funktion.
  205.                Kein Aufwand für den Interrupt (Code + Interruptstruktur).
  206.                Automatisch kompatibel zum serial.device.
  207.      Nachteil: Der Interrupt kommt nicht synchron zum VBlank. (Dies führt
  208.                nur in den seltensten Fällen zu Problemen.)
  209.  
  210.     b) Player die ihren eigenen Interrupt erzeugen.
  211.  
  212.      Vorteil:  Es können andere Interruptquellen benutzt werden
  213.                (z.B. AudioIRQ).
  214.      Nachteil: Erhöhter Aufwand, bei VBlank nicht mehr unabhängig vom
  215.                Videomodus.
  216.  
  217.     Wenn ein eigener Timerinterrupt verwendet wird, sollte die CIAB
  218.     (wg. OS2.0) und die entsprechenden Resourcefunktionen verwendet werden.
  219.     Außerdem ist es sehr sinnvoll die Replayroutine nicht direkt im CIA-B
  220.     TimerInterrupt laufen zu lassen, sondern im Timerinterrupt einen
  221.     Soft-Interrupt mittels Cause() zu generieren. In diesem SoftInt kann
  222.     man dann die eigentliche Replayroutine ablaufen lassen. Das hat den
  223.     Vorteil, daß man wesentlich kompatibler zum serial.device ist. Dies
  224.     liegt daran, daß SoftInt eine niedrigere Priorität als der der RBF
  225.     (Read Buffer Full) Interrupt hat d.h. erst wird der serielle Port
  226.     bedient, dann erst die Replayroutine. Es wird davor gewarnt, direkt
  227.     in die Interruptvektoren zu schreiben! Vom Betriebssystem werden dafür
  228.     die Funktionen AddIntServer() und SetIntVector() zur Verfügung
  229.     gestellt.
  230.  
  231.  
  232.   3.GENIES
  233.  
  234.   Die Funktionalität von DeliTracker kann mit Hilfe von Genies auf viele
  235.   verschiedene Arten erweitert werden. Im Moment existieren vier
  236.   grundsätzlich verschiedene Einsatzgebiete für Genies: die Ausgabe von
  237.   Noten (nicht zu verwechseln mit Playern), das Entpacken und Konvertieren
  238.   von Modulen und schließlich das Analysieren des aktuellen Moduls.
  239.  
  240.     3.1 Generic Kind
  241.  
  242.     Diese Art von Genies ist nicht auf spezielle Aufgaben beschrängt. Es
  243.     kann z.B. diverse Informationen über das Modul anzeigen. Natürlich
  244.     darf weder das Modul noch die Globale Struktur zur Gewinnung dieser
  245.     Informationen verändert werden. Überlicherweise benutzt dieser Genie-
  246.     Typ DTP_InitPlay/DTP_EndPlay um zu erfahren, wann ein neues Modul
  247.     gespielt wird, zusätzlich evtl. auch noch DTP_StartInt/DTP_StopInt.
  248.  
  249.     3.2 Converter
  250.  
  251.     Diese Genies verändern ein Modul. So kann man z.B. das Format des
  252.     Moduls oder seine Länge ändern. Für diese Aufgabe gibt es einen
  253.     speziellen Tag, nämlich DTP_Convert. Er enthält die Adresse der
  254.     Convert-Funktion.
  255.  
  256.     3.3 Decruncher
  257.  
  258.     Diese Art von Genies erweitert die dtg_LoadFile() Funktion von
  259.     DeliTracker. Da sich dieses Interface noch ändern wird, ist es im
  260.     Moment noch nicht dokumentiert.
  261.  
  262.     3.4 Noteplayer
  263.  
  264.     Diese Genies haben die Aufgabe, 'Noten' ggf. zu konvertieren und sie
  265.     auf der jeweiligen Audiohardware auszugeben. Dieses Interface ist zur
  266.     Zeit noch Änderungen unterworfen und deshalb noch nicht dokumentiert.
  267.  
  268.  
  269.   4. TAGS
  270.  
  271.   Außer den SystemTags (TAG_DONE, TAG_IGNORE, TAG_MORE, TAG_SKIP) dürfen
  272.   folgende Tags verwendet werden:
  273.  
  274.   DTP_CustomPlayer (BOOL) - dieser Tag deklariert einen Player als
  275.                 Customplayer.
  276.                 Bei Verwendung dieses Tags sind folgende Tags dann
  277.                 bedeutungslos:  DTP_PlayerVersion
  278.                                 DTP_PlayerName
  279.                                 DTP_Creator
  280.                                 DTP_Check1
  281.                                 DTP_Check2
  282.                                 DTP_ExtLoad
  283.                                 DTP_Config
  284.                                 DTP_UserConfig
  285.  
  286.   DTP_RequestDTVersion (WORD) - damit kann man sicherstellen, daß
  287.                 mindestens eine bestimmte Version von DeliTracker
  288.                 vorhanden ist. Dieser Tag muß angegeben werden, wenn
  289.                 bei den DeliTrackerGlobals neue Funktionspointer
  290.                 hinzugekommen sind und diese vom Player benutzt werden.
  291.                 ti_Data ist dabei die Playerrevision.
  292.  
  293.   DTP_RequestKickVersion (ULONG) - wenn dieser Tag angegeben ist, wird
  294.                 der Player nur noch von von DeliTracker geladen, wenn
  295.                 mindestens die angeforderte Kickstart Version vorhanden
  296.                 ist.
  297.  
  298.   DTP_PlayerVersion (ULONG) - Tag, der die Versionsnummer (high word) und
  299.                 die Revisionsnummer (low word) des Players enthält. Bei
  300.                 zwei Playern mit dem gleichen Playernamen wird derjenige
  301.                 mit der größeren Revisionsnummer geladen.
  302.  
  303.   DTP_PlayerName (STRPTR) - ti_Data enthält den Pointer auf den Namen des
  304.                 Players. Dieser String kann zwar beliebig lang sein aber
  305.                 zur Zeit werden nur die ersten 24 Zeichen angezeigt. Dieser
  306.                 Tag muß existieren!
  307.  
  308.   DTP_Creator (STRPTR) - Pointer auf den Namen des Autors. Dieser wird im
  309.                 Playerfenster im Playerinfofeld angezeigt. Der String
  310.                 kann $A als Zeilenumbruch enthalten.
  311.  
  312.   DTP_Check1 (FPTR) - Pointer auf eine Modulerkennungsroutine, die
  313.                 aufgerufen wird, wenn 1024 Bytes des Moduls geladen sind.
  314.                 Wird das Modul erkannt, liefert sie d0=0, ansonsten d0<>0.
  315.  
  316.   DTP_Check2 (FPTR) - Pointer auf eine Modulerkennungsroutine, die
  317.                 aufgerufen wird, wenn das komplette Modul geladen und evtl.
  318.                 entpackt ist. Wird das Modul erkannt, liefert sie d0=0,
  319.                 ansonsten d0<>0.
  320.  
  321.   DTP_ExtLoad (FPTR) - Pointer auf eine optionale Laderoutine für Module.
  322.                 Ist kein Fehler aufgetreten, wird d0=0 zurückgegeben, sonst
  323.                 d0<>0. Hinweis: Achten Sie darauf, daß im Fehlerfall alle
  324.                 allocierten Ressourcen (Memory, Locks, ...) wieder
  325.                 freigegeben werden, da dann keine weiteren Playerfunktionen
  326.                 mehr angesprungen werden.
  327.  
  328.   DTP_Interrupt (FPTR) - Pointer auf eine Interruptroutine, die mittels
  329.                 eines Timerinterrupts standardmäßig alle 1/50 sec
  330.                 aufgerufen wird. Dies ist die Standardmethode, um mit der
  331.                 richtigen Abspielgeschwindigkeit im PAL/NTSC/Productivity
  332.                 Videomodus zu spielen. Wenn keine DTP_Faster/DTP_Slower
  333.                 Tags angegeben sind, übernimmt DeliTracker dies durch
  334.                 Verändern der Interruptfrequenz. Dieser Tag kann auch nicht
  335.                 existieren, dann müssen aber DTP_StartInt/DTP_StopInt
  336.                 vorhanden sein !
  337.  
  338.   DTP_Stop (FPTR) - Pointer auf eine optionale Stoproutine. Wenn dieser Tag
  339.                 nicht vorhanden ist, verfährt DeliTracker folgendermaßen:
  340.                         Interrupt stoppen (DTP_StopInt)
  341.                         Sound Cleanup (DTP_EndSnd)
  342.                         Song initialisieren (DTP_InitSnd)
  343.                 Ansonsten hat diese Routine die Aufgabe, einen evtl.
  344.                 spielenden Song anzuhalten und so zu initialisieren, daß
  345.                 dieser beim nächsten Starten des Interrupts von Anfang an
  346.                 zu spielen beginnt.
  347.  
  348.   DTP_Config (FPTR) - Pointer auf eine optionale Initialisierungsroutine.
  349.                 Diese wird nur einmal unmittelbar nach dem Laden des
  350.                 Players aufgerufen. Mögliche Anwendungen: Laden einer
  351.                 playerspezifischen Konfigurationsdatei. Ist kein Fehler
  352.                 aufgetreten, muss d0=0 zurückgegeben werden, sonst
  353.                 d0<>0. Hinweis: Im Fehlerfall wird der Player von
  354.                 DeliTracker wieder entfernt!
  355.  
  356.   DTP_UserConfig (FPTR) - Pointer auf eine optionale Initialisierungs-
  357.                 routine. Diese wird nur dann aufgerufen, wenn der User den
  358.                 Player im Setupfenster anwählt und das 'Config' Gadget
  359.                 drückt. Mögliche Anwendungen: Öffnen eines Fensters zum
  360.                 Setzen weiterer Optionen wie z.B. Instrumentenpfad und
  361.                 Abspeichern einer playerspezifischen Konfigurationsdatei.
  362.  
  363.   DTP_SubSongRange (FPTR) - Überholt, bitte DTP_NewSubSongRange benützen!
  364.                 Dieser Tag sollte angegeben werden, wenn der Player
  365.                 MultiModule unterstützt. ti_Data zeigt dabei auf eine
  366.                 Routine, die als Returnwert in d0 die minimale und
  367.                 in d1 die maximale Subsongnummer zurückgeben muß.
  368.                 Hinweis: Wenn möglich sollte dieser Tag (evtl. zusammen
  369.                 mit DTP_SubSongTest) anstelle von DTP_NextSong/DTP_PrevSong
  370.                 verwendet werden.
  371.  
  372.   DTP_InitPlayer (FPTR) - Pointer auf eine optionale Initialsierungs-
  373.                 routine, die aufgerufen wird, wenn ein Modul erfolgreich
  374.                 geladen wurde. Tritt kein Fehler auf, liefert sie d0=0,
  375.                 ansonsten d0<>0. Hier muß die Allocation der Audiokanäle
  376.                 stattfinden! (DeliTracker stellt dafür eine eigene Routine
  377.                 zur Verfügung) Falls der Player Multi-Module unterstützt,
  378.                 muß hier dtg_SndNum(a5) auf die erste Subsongnummer gesetzt
  379.                 werden. Falls eine Routine für DTP_SubSongRange existiert,
  380.                 macht DeliTracker das automatisch (d.h. die Initialisierung
  381.                 von dtg_SndNum(a5) kann weggelassen werden).
  382.  
  383.   DTP_EndPlayer (FPTR) - Pointer auf eine optionale Cleanuproutine, die
  384.                 aufgerufen wird, wenn das Modul aus dem Speicher entfernt
  385.                 wird. Hier muß die Freigabe der Audiokanäle stattfinden!
  386.                 (DeliTracker stellt dafür eine eigene Routine zur
  387.                 Verfügung)
  388.  
  389.   DTP_InitSound (FPTR) - Pointer auf eine optionale Initialsierungsroutine.
  390.                 Diese muß das Modul initialisieren, so daß beim Starten des
  391.                 Interrupts der Song von Anfang an zu spielen beginnt.
  392.  
  393.   DTP_EndSound (FPTR) - Pointer auf eine optionale Cleanuproutine. Diese
  394.                 kann z.B. die Lautstärkeregister und die Audio-DMA
  395.                 rücksetzen.
  396.  
  397.   DTP_StartInt (FPTR) - Pointer auf eine Initialsierungsroutine, die
  398.                 existieren muß, wenn DTP_Interrupt nicht vorhanden ist.
  399.                 In diesem Fall muß hier der Sound gestartet werden.
  400.  
  401.   DTP_StopInt (FPTR) - Pointer auf eine Cleanuproutine, die existieren muß,
  402.                 wenn DTP_Interrupt nicht vorhanden ist. In diesem Fall muß
  403.                 hier der Sound gestoppt werden.
  404.  
  405.   DTP_Volume (FPTR) - Pointer auf eine Funktion, welche die Lautstärke neu
  406.                 setzt. Die Funktion wird aufgerufen, wenn die Volume neu
  407.                 gesetzt wird (Slider, ARexx) und beim Initialisieren des
  408.                 Moduls vor DTP_InitSnd. Die Mastervolume steht in
  409.                 dtg_SndVol(a5). Die Mastervolume ist dabei der maximale
  410.                 Volumewert. Die effektive Volume errechnet sich also
  411.                 durch: VOL_eff = (( dtg_Volume(a5) * modulevolume )>>6)
  412.                 Näheres siehe Beispielsourcen.
  413.  
  414.   DTP_Balance (FPTR) - Pointer auf eine Funktion, welche die Balance neu
  415.                 setzt. Die Funktion wird aufgerufen, wenn die Balance neu
  416.                 gesetzt wird (Slider, ARexx) und beim Initialisieren des
  417.                 Moduls vor DTP_InitSnd. Die Balance für die linken Kanäle
  418.                 steht in dtg_SndLBal(a5), für die rechten Kanäle in
  419.                 dtg_SndRBal(a5). Hinweis: Alle Player die Balance unterstützen
  420.                 können auch Volume! Man verwendet dann die gleiche Routine
  421.                 zum Setzen der Volume&Balance. Die linke Volume errechnet
  422.                 sich wie folgt: (( dtg_Volume(a5) * dtg_SndLBal(a5) )>>6)
  423.                 Entsprechendes gilt für rechts.
  424.  
  425.   DTP_Faster (FPTR) - Pointer auf eine Funktion, die den Abspielvorgang
  426.                 beschleunigt.
  427.  
  428.   DTP_Slower (FPTR) - Pointer auf eine Funktion, die den Abspielvorgang
  429.                 verlangsamt.
  430.  
  431.   DTP_NextPatt (FPTR) - Pointer auf eine Funktion, die den Patternzeiger
  432.                 um eins erhöht.
  433.  
  434.   DTP_PrevPatt (FPTR) - Pointer auf eine Funktion, die den Patternzeiger
  435.                 um eins erniedrigt.
  436.  
  437.   DTP_NextSong (FPTR) - Pointer auf eine Funktion, die Subsongnummer auf
  438.                 den nächsten Subsong setzt und diesen spielt.
  439.                 (Falls vorhanden)
  440.  
  441.   DTP_PrevSong (FPTR) - Pointer auf eine Funktion, die Subsongnummer auf
  442.                 den vorhergehenden Subsong setzt und diesen spielt.
  443.                 (Falls vorhanden)
  444.  
  445.   ;--- tags in revision 14 or higher (distributed as Release 1.35) ---
  446.  
  447.   DTP_SubSongTest (FPTR) - Dieser Tag wird nur ausgewertet, wenn schon der
  448.                 Tag DTP_SubSongRange angegeben wurde. ti_Data zeigt dabei
  449.                 auf eine Routine, die als Returnwert in d0 einen Boolschen
  450.                 Wert zurückliefert. Dieser gibt an, ob der SubSong mit
  451.                 Nummer dtg_SndNum(a5) gültig ist (d0=0) oder nicht (d0<>0).
  452.                 Dieser Tag ist nur bei den Playern nötig, bei denen nicht
  453.                 jeder SubSong (innerhalb der durch DTP_SubSongRange
  454.                 festgelegten Grenzen) benutzt ist.
  455.  
  456.   ;--- tags in revision 16 or higher (distributed as Release 2.01) ---
  457.  
  458.   DTP_NewSubSongRange (APTR) - erweiterter Ersatz für DTP_SubSongRange.
  459.                 Dieser Tag sollte angegeben werden, wenn der Player
  460.                 MultiModule unterstützt. ti_Data zeigt dabei auf ein
  461.                 Array mit drei WORDs: Das erste Word enthält die Nummer
  462.                 des Subsongs, der als erstes gespielt werden soll. Das
  463.                 zweite enthält die minimale und das dritte die maximale
  464.                 Subsong Nummer. In den meisten Fällen ist das erste und
  465.                 das zweite WORD identisch.
  466.  
  467.   DTP_DeliBase (APTR) - die Adresse eines Pointers, wo DeliTracker einen
  468.                 Pointer auf die DeliGlobals ablegt.
  469.  
  470.   DTP_Flags (ULONG) - enthält verschiedene Flags.
  471.                 Derzeit sind folgende Flags definiert:
  472.                 PLYF_CUSTOM     - der Player ist ein Customplayer
  473.                 PLYF_SONGEND    - dieser Player unterstützt Songend
  474.                 PLYF_ANYMEM     - die Moduldaten dieses Players brauchen
  475.                                   nicht im ChipMem abgelegt werden.
  476.  
  477.   DTP_CheckLen (ULONG) - Länge des Check Codes. Dieser Tag darf nur benutzt
  478.                 werden, wenn der Checkcode PC-relativ und reentrant ist!
  479.                 Wenn der Tag benutzt wird, lagert DeliTracker den Player in
  480.                 LowMem-Situationen aus. Bei Playern, die als Process laufen,
  481.                 ist dieser Tag ohne Wirkung.
  482.  
  483.   DTP_Description (APTR) - Pointer auf einen String mit einer Beschreibung,
  484.                 was der Player bzw. das Genie tut und welche besonderen
  485.                 Fähigkeiten es hat. Dieser String kann $A als Zeilenumbruch
  486.                 enthalten.
  487.  
  488.   DTP_Decrunch (FPTR) - private, still under development!
  489.  
  490.   DTP_Convert (FPTR) - Pointer auf eine Routine zum Konvertieren eines
  491.                 Moduls. Diese Routine wird aufgerufen, wenn das Modul
  492.                 geladen und ggf. entpackt ist. Sie dient dazu, das Modul
  493.                 in ein neues Format umzukonvertieren. Die Konvertier-
  494.                 Routine funktioniert üblicherweise folgendermassen:
  495.                         1) Ausgangs-Format erkennen
  496.                         2) Speicher für Ziel-Format mit dtg_AllocListData()
  497.                            belegen
  498.                         3) Das Modul vom Ausgangsformat ins Zielformat
  499.                            konvertieren
  500.                 Diese Routine muß NULL zurückliefern, wenn das Modul
  501.                 erfolgreich konvertiert wurde (success), ansonsten -1
  502.                 (error). Auf gar keinen Fall darf das Ausgangs-Modul von
  503.                 der Konvertier-Funktion verändert werden!
  504.                 Bemerkung: für temporäre Speicher-Allocationen sollte man
  505.                 die entsprechenden Exec-Funktionen benutzen, der Speicher
  506.                 für das Ziel-Modul muß aber in jedem Fall mit der Support
  507.                 Funktion dtg_AllocListData() belegt werden!
  508.  
  509.   DTP_NotePlayer (APTR) - private, still under development!
  510.  
  511.   DTP_NoteStruct (APTR) - private, still under development!
  512.  
  513.   DTP_NoteInfo (APTR) - private, still under development!
  514.  
  515.   DTP_NoteSignal (FPTR) - private, still under development!
  516.  
  517.   DTP_Process (FPTR) - Pointer auf einen Code, der als Prozess gestartet
  518.                 werden soll. Wenn dieser Tag verwendet wird, startet
  519.                 DeliTracker den Player bzw. das Genie als eigenen Prozess.
  520.  
  521.   DTP_Priority (BYTE) -  Priorität des zu startenden Prozesses. Nur in
  522.                 Verbindung mit DTP_Process sinnvoll. Wenn dieser Tag nicht
  523.                 angegeben wird, wird der Prozess mit der gleichen Prioriät
  524.                 wie DeliTracker gestartet.
  525.  
  526.   DTP_StackSize (ULONG) - Stack-Größe des zu startenden Prozesses. Nur in
  527.                 Verbindung mit DTP_Process sinnvoll. Wenn dieser Tag nicht
  528.                 angegeben wird, wird die Stackgröße auf 4096 Bytes gesetzt.
  529.  
  530.   DTP_MsgPort (APTR) - Adresse eines Pointer, wo DeliTracker die Adresse
  531.                 des Ports ablegt, an den dann die Messages geschickt
  532.                 werden. Nur in Verbindung mit DTP_Process sinnvoll.
  533.  
  534.   DTP_Appear (FPTR) - Pointer auf eine Routine die die GUI des Players bzw.
  535.                 Genies öffnet/aktiviert. Als Returnwert muß der alte
  536.                 Windowzustand (<>0 wenn das Fenster auf war, ansonsten 0)
  537.                 zurückgeliefert werden. Bemerkung: Stellen Sie sicher, daß
  538.                 die GUI auf dem richtigen Screen geöffnet wird! (benützen
  539.                 Sie dazu die dtg_LockPubScreen() und dtg_UnLockPubScreen()
  540.                 Funktionen).
  541.  
  542.   DTP_Disappear (FPTR) - Pointer auf eine Routine, die die GUI schliesst.
  543.                 Diese Routine muss den alten Windowzustand (<>0 wenn das
  544.                 Fenster auf war, ansonsten 0) zurückgeliefern.
  545.  
  546.   DTP_ModuleName (APTR) - Adresse eines Pointers, der auf den tatsächlichen
  547.                 Namen des Moduls zeigt (dieser String muß mit NULL
  548.                 abgeschlossen sein). Dieser Tag ist nur für Player sinnvoll
  549.                 und wird nach InitPlay() ausgewertet.
  550.  
  551.   DTP_FormatName (APTR) - Adresse eines Pointers, der auf den Namen des
  552.                 urspünglichen Modulformats zeigt (dieser String muß mit
  553.                 NULL abgeschlossen sein). Dieser Tag ist nur für Genies
  554.                 sinnvoll und wird nach der Convert() Funktion ausgewertet.
  555.  
  556.   DTP_AuthorName (APTR) - not implemented yet!
  557.  
  558.   ;--- tags in revision 17 or higher (distributed as Release 2.07) ---
  559.  
  560.   DTP_InitNote (FPTR) - private, still under development!
  561.  
  562.   DTP_PlayTime (APTR) - not implemented yet!
  563.  
  564.  
  565.  
  566.   5.DELITRACKER SUPPORT FUNKTIONEN
  567.  
  568.   DeliTracker stellt zur Erleichterung der Playeranpassung einige
  569.   Funktionen zur Verfügung. Eine Funktion wird wie folgt aufgerufen:
  570.  
  571.         move.l  dtg_XXX(a5),a0
  572.         jsr     (a0)
  573.  
  574.   Alle folgenden Funktionen außer dtg_SongEnd, dtg_SetTimer und
  575.   dtp_NotePlayer verwenden d0/d1/a0/a1 als Scratchregister. In a5 muß bei
  576.   allen Aufrufen (außer bei dtg_SongEnd, dtg_SetTimer und dtp_NotePlayer)
  577.   der Pointer auf die Base stehen. Derzeit existieren folgende Funktionen:
  578.  
  579.   dtg_GetListData
  580.  
  581.         SYNOPSIS
  582.                 memory size = dtg_GetListData(number)
  583.                 A0     D0                     D0.l
  584.  
  585.         FUNCTION
  586.                 Liefert Adresse und Länge eines mit LoadFile() geladenen
  587.                 Files.
  588.  
  589.         INPUTS
  590.                 number - Nummer eines Files beginnend mit 0 für das vom
  591.                          User selektierte File.
  592.  
  593.         RESULT
  594.                 memory - ein Pointer auf die Startadresse des Files im
  595.                          Speicher oder NULL im Fehlerfall.
  596.                 size - Länge des Files in Bytes bzw. 0 im Fehlerfall.
  597.  
  598.  
  599.   dtg_LoadFile
  600.  
  601.         SYNOPSIS
  602.                 success = dtg_LoadFile(name)
  603.  
  604.         FUNCTION
  605.                 Lädt und entpackt ggf. das angegebene File ins Chip-
  606.                 Memory. (Hinweis: diese Funktion ergänzt automatisch,
  607.                 falls das File mit dem angegebenen Namen nicht geöffnet
  608.                 werden konnte '.pp','.im' und '.xpk')
  609.  
  610.         INPUTS
  611.                 name - der Filename steht in einem internen Buffer (seine
  612.                        Adresse steht in dtg_PathArray)
  613.  
  614.         RESULT
  615.                 success - alles ok d0.l=0, sonst d0.l<>0.
  616.  
  617.  
  618.   dtg_CopyDir
  619.  
  620.         SYNOPSIS
  621.                 dtg_CopyDir()
  622.  
  623.         FUNCTION
  624.                 Kopiert das Directory des von User angewählten Files an das
  625.                 Ende des Strings, auf den dtg_PathArray(a5) zeigt.
  626.  
  627.  
  628.   dtg_CopyFile
  629.  
  630.         SYNOPSIS
  631.                 dtg_CopyFile()
  632.  
  633.         FUNCTION
  634.                 Kopiert den Filenamen des von User angewählten Files an das
  635.                 Ende des Strings, auf den dtg_PathArray(a5) zeigt.
  636.  
  637.  
  638.   dtg_CopyString
  639.  
  640.         SYNOPSIS
  641.                 dtg_CopyString(string)
  642.                                A0
  643.  
  644.         FUNCTION
  645.                 Kopiert den String, auf den das Register a0 zeigt, an das
  646.                 Ende des Strings, auf den dtg_PathArray(a5) zeigt.
  647.  
  648.         INPUTS
  649.                 string - der Pointer auf den anzuhängenden String steht
  650.                          in a0
  651.  
  652.  
  653.   dtg_AudioAlloc
  654.  
  655.         SYNOPSIS
  656.                 success = dtg_AudioAlloc()
  657.  
  658.         FUNCTION
  659.                 Belegt alle Audiokanäle.
  660.  
  661.         RESULT
  662.                 success - alles ok d0.l=0, sonst d0.l<>0.
  663.  
  664.  
  665.   dtg_AudioFree
  666.  
  667.         SYNOPSIS
  668.                 dtg_AudioFree()
  669.  
  670.         FUNCTION
  671.                 Gibt die mit dtg_AudioAlloc belegten Audiokanäle wieder
  672.                 frei.
  673.  
  674.  
  675.   dtg_StartInt
  676.  
  677.         SYNOPSIS
  678.                 dtg_StartInt()
  679.  
  680.         FUNCTION
  681.                 Startet den Soundinterrupt. (Falls er nicht schon läuft.)
  682.                 Falls DTP_Interrupt existiert, startet DeliTracker einen
  683.                 Timerinterrupt, ansonsten wird DTP_StartInt aufgerufen.
  684.  
  685.  
  686.   dtg_StopInt
  687.  
  688.         SYNOPSIS
  689.                 dtg_StopInt()
  690.  
  691.         FUNCTION
  692.                 Stoppt den Soundinterrupt. (Falls er nicht schon angehalten
  693.                 ist.) Falls DTP_Interrupt existiert, stoppt DeliTracker
  694.                 seinen Timerinterrupt, ansonsten wird DTP_StopInt
  695.                 aufgerufen.
  696.  
  697.  
  698.   dtg_SongEnd
  699.  
  700.         SYNOPSIS
  701.                 dtg_SongEnd()
  702.  
  703.         FUNCTION
  704.                 Signalisiert DeliTracker, daß das Modul einmal komplett
  705.                 gespielt wurde. Diese Funktion verändert keine Register
  706.                 und darf auch von Interrupts aufgerufen werden.
  707.  
  708.  
  709.   dtg_CutSuffix
  710.  
  711.         SYNOPSIS
  712.                 dtg_CutSuffix()
  713.  
  714.         FUNCTION
  715.                 Entfernt am Ende des Strings, auf den dtg_PathArray(a5)
  716.                 zeigt ggf. die Endung '.pp', '.im' oder '.xpk'
  717.  
  718.  
  719.   ;------ extensions in revision 14 (distributed as Release 1.34)
  720.  
  721.   dtg_SetTimer
  722.  
  723.         SYNOPSIS
  724.                 dtg_SetTimer()
  725.  
  726.         FUNCTION
  727.                 Programmiert den CIA-Timer mit dem Wert, der sich in
  728.                 dtg_Timer(a5) befindet. Diese Funktion verändert keine
  729.                 Register und darf auch von Interrupts aufgerufen werden.
  730.  
  731.  
  732.   ;------ extensions in revision 15 (distributed as Release 1.37)
  733.  
  734.   dtg_WaitAudioDMA
  735.  
  736.         SYNOPSIS
  737.                 dtg_WaitAudioDMA()
  738.  
  739.         FUNCTION
  740.                 Diese Funktion wartet eine bestimmte Zeit lang. Die
  741.                 Zeitspanne sollte für die Audio Hardware normalerweise
  742.                 groß genug sein, um neue Werte zu laden. Dieser Aufruf ist
  743.                 nur erlaubt, wenn der interne Timer-Interrupt benutzt wird.
  744.                 Er kann anstelle der üblichen dbra oder Rasterline
  745.                 Warteschleifen benutzt werden. Diese Funktion verändert
  746.                 keine Register.
  747.  
  748.         BUGS
  749.                 Wenn der Player auch Periods unterstützt, die viel größer
  750.                 als 1000 sind, wird evtl. nicht lange genug gewartet.
  751.  
  752.  
  753.   ;------ extensions in revision 16 (distributed as release 2.01)
  754.  
  755.   dtg_LockScreen
  756.  
  757.         SYNOPSIS
  758.                 screen = dtg_LockScreen()
  759.                 D0
  760.  
  761.         FUNCTION
  762.                 Lockt den Screen auf dem DeliTracker läuft (ist immer
  763.                 ein Pubscreen).
  764.  
  765.         RESULT
  766.                 Pointer auf den Screen in d0 oder NULL im Fehlerfall.
  767.  
  768.  
  769.   dtg_UnlockScreen
  770.  
  771.         SYNOPSIS
  772.                 dtg_UnlockScreen()
  773.  
  774.         FUNCTION
  775.                 Diese Function unlockt den Screen, auf dem DeliTracker
  776.                 läuft. Hinweis: diese Funktion keinesfalls öfters aufrufen
  777.                 als dtg_LockScreen()!).
  778.  
  779.  
  780.   dtg_NotePlayer
  781.  
  782.         SYNOPSIS
  783.                 dtg_NotePlayer()
  784.  
  785.  
  786.         FUNCTION
  787.                 Dieser Aufruf spielt die Noten, die in der aktuellen
  788.                 NoteStruct Struktur angegeben sind. Die Funktion darf
  789.                 nicht aufgerufen werden, wenn der aktive Player keine
  790.                 NotePlayer Structur hat.
  791.                 Hinweis: Dieser Aufruf sichert alle Register und darf
  792.                 sogar von Interrupts aufgerufen werden, solange das
  793.                 Interrupt Level 4 oder kleiner ist.
  794.  
  795.         INPUTS
  796.                 aktuelle NoteStruct.
  797.  
  798.  
  799.   dtg_AllocListData
  800.  
  801.         SYNOPSIS
  802.                 memory = dtg_AllocListData(byteSize,Flags)
  803.                 D0                         D0.l     D1.l
  804.  
  805.  
  806.         FUNCTION
  807.                 Dies ist die Funktion, um Modul-spezifischen Speicher von
  808.                 Playern oder Genies aus zu belegen. Es gibt die Möglichkeit
  809.                 anzugeben, ob die Allocation im Chipmem oder Publicmem
  810.                 gemacht werden soll. Wenn die Allocation erfolgreich war,
  811.                 merkt DeliTracker sich den Memblock und man kann mit der
  812.                 Funktion dtg_GetListData() die Adresse und die Größe des
  813.                 Blocks erfahren.
  814.  
  815.  
  816.         INPUTS
  817.                 byteSize - Größe des gewünschten Blocks in Bytes.
  818.  
  819.                 Flags - die Flags werden an AllocMem() weitergereicht.
  820.  
  821.         RESULT
  822.                 Ein Pointer auf den allocierten Memoryblock wird in d0
  823.                 zurückgeliefert. Wenn nicht genug freier Speicher vorhanden
  824.                 ist, um die Anforderung zu erfüllen, wird Null
  825.                 zurückgegeben. Der Pointer muß auf jeden Fall getestet
  826.                 werden und darf nur benutzt werden, wenn er ungleich Null
  827.                 ist.
  828.  
  829.  
  830.   dtg_FreeListData
  831.  
  832.         SYNOPSIS
  833.                 dtg_FreeListData(memoryBlock)
  834.                                  A1
  835.  
  836.         FUNCTION
  837.                 Gibt einen Speicherblock frei, der mit AllocListData(),
  838.                 allociert wurde.
  839.  
  840.         INPUTS
  841.                 memoryBlock - Pointer auf den Speicherblock, darf auch
  842.                               NULL sein.
  843.  
  844.